#include "tatums.h"


void tatumsFrameListener::updateScore(void)
	{
		static String currPlayer = "Player Score: ";
		static String pl1Score = "Time since start";
		static String pl2Score = "tat value";
		static String fireSpeed = "";
		static String roundTime = "currentTatumindex";
		static String gameTime = "animation timer";

		
		// update stats when necessary
		try {
			OverlayElement* currPl = OverlayManager::getSingleton().getOverlayElement("Example/Asg2/CurrPlayer");
			OverlayElement* pl1Sc = OverlayManager::getSingleton().getOverlayElement("Example/Asg2/Pl1Score");
			OverlayElement* pl2Sc = OverlayManager::getSingleton().getOverlayElement("Example/Asg2/Pl2Score");
			OverlayElement* fSpd = OverlayManager::getSingleton().getOverlayElement("Example/Asg2/FireSpeed");
			OverlayElement* rdTime = OverlayManager::getSingleton().getOverlayElement("Example/Asg2/RoundTime");
			OverlayElement* gmTime = OverlayManager::getSingleton().getOverlayElement("Example/Asg2/GameTime");

			currPl->setCaption(currPlayer + StringConverter::toString(playerScore));
				
			pl1Sc->setCaption(pl1Score + StringConverter::toString(timeSinceStart));
			//pl2Sc->setCaption(pl2Score + StringConverter::toString(*(tatums + currentTatumIndex)));
			//pl2Sc->setCaption(pl2Score + StringConverter::toString((*segments)[currentTatumIndex]->getStart()));
			pl2Sc->setCaption(pl2Score + StringConverter::toString((*bo)[currentBoIndex]->m_tatum));

			//rdTime->setCaption(roundTime + StringConverter::toString(currentTatumIndex));
			rdTime->setCaption(roundTime + StringConverter::toString(currentBoIndex));
			gmTime->setCaption(gameTime + StringConverter::toString(animationTimer_w));
						
		}
		catch(...) { }// ignore  
	}

bool tatumsFrameListener::frameStarted(const FrameEvent &evt)
    {
        if(mMouse)
            mMouse->capture();
        if(mKeyboard) 
            mKeyboard->capture();

		timeSinceStart += evt.timeSinceLastFrame;
		//timeSinceStart = mSound->timesincestart();
		//if (*(tatums + currentTatumIndex) < (timeSinceStart))///1000))
		//if ((*segments)[currentTatumIndex]->getStart() < (timeSinceStart))///1000))
		if((*bo)[currentBoIndex]->m_tatum < timeSinceStart)
		{
			//switch(keyToPress[currentTatumIndex])
			switch((*bo)[currentBoIndex]->m_char)
			{
			case 'w':
				//show binding box for a second;
				if (show_w)
				{
					//currentTatumIndex = currentTatumIndex + ((int)(numTatumsPerBeat) * gameLevel);
					currentBoIndex+=2;
					show_w = false;
					mSceneMgr->getSceneNode("WNode")->scale(2,2,2);
					mSceneMgr->getSceneNode("WNode")->showBoundingBox(true);
					/*mAnimationState_w =mSceneMgr->getEntity("W")->getAnimationState("pulse");
					mAnimationState_w->setLoop(false);
					mAnimationState_w->setEnabled(true);*/
					animationTimer_w = animation_timer_value;
				}
				break;
			case 'a':
				//show binding box for a second;
				if (show_a)
				{
					//currentTatumIndex = currentTatumIndex + ((int)(numTatumsPerBeat) * gameLevel);
					currentBoIndex+=2;
					show_a = false;
					mSceneMgr->getSceneNode("ANode")->scale(2,2,2);
					mSceneMgr->getSceneNode("ANode")->showBoundingBox(true);
					/*mAnimationState_a =mSceneMgr->getEntity("A")->getAnimationState("pulse");
					mAnimationState_a->setLoop(false);
					mAnimationState_a->setEnabled(true);*/
					animationTimer_a = animation_timer_value;
				}
				break;
			case 's':
				//show binding box for a second;
				if (show_s)
				{
					//currentTatumIndex = currentTatumIndex + ((int)(numTatumsPerBeat) * gameLevel);
					currentBoIndex+=2;
					show_s = false;
					mSceneMgr->getSceneNode("SNode")->scale(2,2,2);
					mSceneMgr->getSceneNode("SNode")->showBoundingBox(true);
					/*mAnimationState_s =mSceneMgr->getEntity("S")->getAnimationState("pulse");
					mAnimationState_s->setLoop(false);
					mAnimationState_s->setEnabled(true);*/
					animationTimer_s = animation_timer_value;
				}
				break;
			case 'd':
				//show binding box for a second;
				if (show_d)
				{
					//currentTatumIndex = currentTatumIndex + ((int)(numTatumsPerBeat) * gameLevel);
					currentBoIndex+=2;
					show_d = false;
					mSceneMgr->getSceneNode("DNode")->scale(2,2,2);
					mSceneMgr->getSceneNode("DNode")->showBoundingBox(true);
					/*mAnimationState_d =mSceneMgr->getEntity("D")->getAnimationState("pulse");
					mAnimationState_d->setLoop(false);
					mAnimationState_d->setEnabled(true);*/
					animationTimer_d = animation_timer_value;
				}
				break;
			}
		}

		if ((!show_w) && (animationTimer_w <= 0))
		{
			mSceneMgr->getSceneNode("WNode")->showBoundingBox(false);
			mSceneMgr->getSceneNode("WNode")->scale(.5,.5,.5);
			show_w = true;
		}
		if (animationTimer_w >= 0)
		{
			animationTimer_w -= evt.timeSinceLastFrame;
		}

		if ((!show_a) && (animationTimer_a <= 0))
		{
			mSceneMgr->getSceneNode("ANode")->showBoundingBox(false);
			mSceneMgr->getSceneNode("ANode")->scale(.5,.5,.5);
			show_a = true;
		}
		if (animationTimer_a >= 0)
		{
			animationTimer_a -= evt.timeSinceLastFrame;
		}

		if ((!show_s) && (animationTimer_s <= 0))
		{
			mSceneMgr->getSceneNode("SNode")->showBoundingBox(false);
			mSceneMgr->getSceneNode("SNode")->scale(.5,.5,.5);
			show_s = true;
		}
		if (animationTimer_s >= 0)
		{
			animationTimer_s -= evt.timeSinceLastFrame;
		}

		if ((!show_d) && (animationTimer_d <= 0))
		{
			mSceneMgr->getSceneNode("DNode")->showBoundingBox(false);
			mSceneMgr->getSceneNode("DNode")->scale(.5,.5,.5);
			show_d = true;
		}
		if (animationTimer_d >= 0)
		{
			animationTimer_d -= evt.timeSinceLastFrame;
		}
        mCamNode->translate(mDirection * evt.timeSinceLastFrame, Node::TS_LOCAL);
		updateScore();
        return mContinue;
		
    }

    // MouseListener
bool tatumsFrameListener::mouseMoved(const OIS::MouseEvent &e)
    {
       if (e.state.buttonDown(OIS::MB_Right))
       {
           mCamNode->yaw(Degree(-mRotate * e.state.X.rel), Node::TS_WORLD);
           mCamNode->pitch(Degree(-mRotate * e.state.Y.rel), Node::TS_LOCAL);
       }
		else
		{
			// Update CEGUI with the mouse motion
	       CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel, e.state.Y.rel);
		}
       return true;
    }

bool tatumsFrameListener::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
    {
        Light *light = mSceneMgr->getLight("Light1");
        switch (id)
        {
        case OIS::MB_Left:
            light->setVisible(! light->isVisible());
            break;
		case OIS::MB_Right:
			CEGUI::MouseCursor::getSingleton().hide();
			break;
        }
        return true;
    }

bool tatumsFrameListener::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) 
	{
		switch (id)
		   {
			   case OIS::MB_Right:
				    CEGUI::MouseCursor::getSingleton().show();
					break;
		}
		return true; 
	}

    // KeyListener
bool tatumsFrameListener::keyPressed(const OIS::KeyEvent &e)
    {
        switch (e.key)
        {
        case OIS::KC_ESCAPE: 
            mContinue = false;
            break;

        case OIS::KC_1:
            mCamera->getParentSceneNode()->detachObject(mCamera);
            mCamNode = mSceneMgr->getSceneNode("CamNode1");
            mCamNode->attachObject(mCamera);
            break;

        case OIS::KC_2:
            mCamera->getParentSceneNode()->detachObject(mCamera);
            mCamNode = mSceneMgr->getSceneNode("CamNode2");
            mCamNode->attachObject(mCamera);
            break;

        case OIS::KC_UP:
            mDirection.z -= mMove;
            break;


        case OIS::KC_DOWN:
            mDirection.z += mMove;
            break;

        case OIS::KC_LEFT:
            mDirection.x -= mMove;
            break;

        case OIS::KC_RIGHT:
            mDirection.x += mMove;
            break;

        case OIS::KC_PGDOWN:
        case OIS::KC_E:
            mDirection.y -= mMove;
            break;

        case OIS::KC_PGUP:
        case OIS::KC_Q:
            mDirection.y += mMove;
            break;

		case OIS::KC_W:
			if(!show_w)
			{
				if (animationTimer_w > 0 )
				{
					
					playerScore = playerScore + (int)((animationTimer_w/animation_timer_value)*10);
					// play good animation
					/*mAnimationState_w =mSceneMgr->getEntity("W")->getAnimationState("jiggle");
					mAnimationState_w->setLoop(false);
					mAnimationState_w->setEnabled(true);*/
					//set the animation timer to zero
					animationTimer_w = -1;
				}
			}
			else
			{
				--playerScore;
				//play bad animation
				/*mAnimationState_w =mSceneMgr->getEntity("W")->getAnimationState("squish");
				mAnimationState_w->setLoop(false);
				mAnimationState_w->setEnabled(true);*/
			}

			break;

		case OIS::KC_S:
			if(!show_s)
			{
				if (animationTimer_s > 0 )
				{
					
					playerScore = playerScore + (int)((animationTimer_s/animation_timer_value)*10);
					// play good animation
					/*mAnimationState_s =mSceneMgr->getEntity("S")->getAnimationState("jiggle");
					mAnimationState_s->setLoop(false);
					mAnimationState_s->setEnabled(true);*/
					//set the animation timer to zero
					animationTimer_s = -1;
				}
			}
			else
			{
				--playerScore;
				//play bad animation
				/*mAnimationState_s =mSceneMgr->getEntity("S")->getAnimationState("squish");
				mAnimationState_s->setLoop(false);
				mAnimationState_s->setEnabled(true);*/
			}
			break;


		case OIS::KC_A:
			if(!show_a)
			{
				if (animationTimer_a > 0 )
				{
					
					playerScore = playerScore + (int)((animationTimer_a/animation_timer_value)*10);
					// play good animation
					/*mAnimationState_a =mSceneMgr->getEntity("A")->getAnimationState("jiggle");
					mAnimationState_a->setLoop(false);
					mAnimationState_a->setEnabled(true);*/
					//set the animation timer to zero
					animationTimer_a = -1;
				}
			}
			else
			{
				--playerScore;
				/*mAnimationState_a =mSceneMgr->getEntity("A")->getAnimationState("squish");
				mAnimationState_a->setLoop(false);
				mAnimationState_a->setEnabled(true);*/
			}
			break;


		case OIS::KC_D:
			if(!show_d)
			{
				if (animationTimer_d > 0 )
				{
					
					playerScore = playerScore + (int)((animationTimer_d/animation_timer_value)*10);
					// play good animation
					//mAnimationState_d =mSceneMgr->getEntity("D")->getAnimationState("jiggle");
					//mAnimationState_d->setLoop(false);
					//mAnimationState_d->setEnabled(true);
					//set the animation timer to zero
					animationTimer_d = -1;
				}
			}
			else
			{
				--playerScore;
				//play bad animation
				//mAnimationState_d =mSceneMgr->getEntity("D")->getAnimationState("squish");
				//mAnimationState_d->setLoop(false);
				//mAnimationState_d->setEnabled(true);
			}
			break;
        }
        return true;
    }

bool tatumsFrameListener::keyReleased(const OIS::KeyEvent &e)
    {
        switch (e.key)
        {
        case OIS::KC_UP:
            mDirection.z += mMove;
            break;

        case OIS::KC_DOWN:
            mDirection.z -= mMove;
            break;

        case OIS::KC_LEFT:
            mDirection.x += mMove;
            break;

        case OIS::KC_RIGHT:
            mDirection.x -= mMove;
            break;

        case OIS::KC_PGDOWN:
        case OIS::KC_E:
            mDirection.y += mMove;
            break;

        case OIS::KC_PGUP:
        case OIS::KC_Q:
            mDirection.y -= mMove;
            break;

		case OIS::KC_W:
			break;
		case OIS::KC_S:
			break;
		case OIS::KC_A:
			break;
		case OIS::KC_D:
			break;
        } // switch
        return true;
    }





void tatumsApp::createCamera(void)
    {
        // create camera, but leave at default position
        mCamera = mSceneMgr->createCamera("PlayerCam"); 
        mCamera->setNearClipDistance(5);
		//mCamera->lookAt(Ogre::Vector3(0,0,0));
    }

void tatumsApp::createScene(void)
    {
        mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));

        // add the ninja
        Entity *ent = mSceneMgr->createEntity("W", "W.mesh");
        SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("WNode",Ogre::Vector3(0,40,0));
        node->attachObject(ent);
		ent->setMaterialName("Examples/BumpyMetal");
		
		
		

		ent = mSceneMgr->createEntity("A", "A.mesh");
		node = mSceneMgr->getRootSceneNode()->createChildSceneNode("ANode",Ogre::Vector3(-40,0,0));
		node->attachObject(ent);
		ent->setMaterialName("Examples/BumpyMetal");
		

		ent = mSceneMgr->createEntity("S", "S.mesh");
		node = mSceneMgr->getRootSceneNode()->createChildSceneNode("SNode",Ogre::Vector3(0,0,0));
		node->attachObject(ent);
		ent->setMaterialName("Examples/BumpyMetal");
		

		ent = mSceneMgr->createEntity("D", "D.mesh");
		node = mSceneMgr->getRootSceneNode()->createChildSceneNode("DNode",Ogre::Vector3(40,0,0));
		node->attachObject(ent);
		ent->setMaterialName("Examples/BumpyMetal");
		

		 // Create a skydome
        mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

        // create the light
        Light *light = mSceneMgr->createLight("Light1");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(250, 150, 250));
        light->setDiffuseColour(ColourValue::White);
        light->setSpecularColour(ColourValue::White);

        // Create the cam node
        node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode1", Vector3(0, 18, 110));
        node->attachObject(mCamera);
		node->lookAt(Ogre::Vector3(0,25,0),Ogre::Node::TransformSpace::TS_WORLD);

        // create the second camera node/pitch node
		node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode2", Vector3(-100, 10, 300));
        node->yaw(Degree(-45));

		// load scheme and set up defaults
		mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);
		mGUISystem = new CEGUI::System(mGUIRenderer);

        CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLookSkin.scheme");
        mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
        mGUISystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12");

       // CEGUI::Window* sheet = CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)"my.layout"); 
        //mGUISystem->setGUISheet(sheet);

    }

void tatumsApp::createFrameListener(void)
    {
        // Create the FrameListener
        mFrameListener = new tatumsFrameListener(mWindow, mCamera, mSceneMgr);
        mRoot->addFrameListener(mFrameListener);

        // Show the frame stats overlay
        mFrameListener->showDebugOverlay(true);
    }




#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    tatumsApp app;

    try {
        app.go();
    } catch(Exception& e) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occurred: %s\n",
            e.getFullDescription().c_str());
#endif
    }

    return 0;
}
